package com.rickpan.aspect;

import com.rickpan.annotation.RequirePermission;
import com.rickpan.enums.Permission;
import com.rickpan.exception.PermissionDeniedException;
import com.rickpan.security.UserDetailsServiceImpl;
import com.rickpan.service.PermissionService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

/**
 * 权限检查AOP切面
 */
@Aspect
@Component
public class PermissionAspect {

    private static final Logger logger = LoggerFactory.getLogger(PermissionAspect.class);

    @Autowired
    private PermissionService permissionService;

    /**
     * 权限检查切点
     */
    @Before("@annotation(requirePermission)")
    public void checkPermission(JoinPoint joinPoint, RequirePermission requirePermission) {
        try {
            // 获取当前用户
            Long userId = getCurrentUserId();
            if (userId == null) {
                throw new PermissionDeniedException("用户未登录");
            }

            // 检查管理员权限
            if (requirePermission.requireAdmin() && !permissionService.isAdmin(userId)) {
                throw new PermissionDeniedException("需要管理员权限");
            }

            // 检查VIP权限
            if (requirePermission.requireVip() && !permissionService.isVip(userId)) {
                throw new PermissionDeniedException("需要VIP权限");
            }

            // 检查具体权限
            Permission[] permissions = requirePermission.value();
            if (permissions.length > 0) {
                List<Permission> permissionList = Arrays.asList(permissions);
                boolean requireAll = requirePermission.operator() == RequirePermission.LogicalOperator.AND;
                
                if (!permissionService.hasPermissions(userId, permissionList, requireAll)) {
                    String message = requirePermission.message();
                    if ("权限不足".equals(message)) {
                        message = buildPermissionMessage(permissions, requireAll);
                    }
                    throw new PermissionDeniedException(message);
                }
            }

            logger.debug("权限检查通过 userId={}, method={}", userId, joinPoint.getSignature().getName());

        } catch (PermissionDeniedException e) {
            logger.warn("权限检查失败: {}, method={}", e.getMessage(), joinPoint.getSignature().getName());
            throw e;
        } catch (Exception e) {
            logger.error("权限检查异常 method={}", joinPoint.getSignature().getName(), e);
            throw new PermissionDeniedException("权限检查失败");
        }
    }

    /**
     * 获取当前登录用户ID
     */
    private Long getCurrentUserId() {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication == null || !authentication.isAuthenticated()) {
                return null;
            }

            Object principal = authentication.getPrincipal();
            if (principal instanceof UserDetailsServiceImpl.UserPrincipal) {
                return ((UserDetailsServiceImpl.UserPrincipal) principal).getId();
            }

            return null;
        } catch (Exception e) {
            logger.error("获取当前用户ID失败", e);
            return null;
        }
    }

    /**
     * 构建权限错误消息
     */
    private String buildPermissionMessage(Permission[] permissions, boolean requireAll) {
        if (permissions.length == 1) {
            return "缺少权限: " + permissions[0].getDescription();
        }

        StringBuilder message = new StringBuilder();
        if (requireAll) {
            message.append("缺少权限: ");
            for (int i = 0; i < permissions.length; i++) {
                if (i > 0) message.append("、");
                message.append(permissions[i].getDescription());
            }
        } else {
            message.append("需要以下任一权限: ");
            for (int i = 0; i < permissions.length; i++) {
                if (i > 0) message.append("、");
                message.append(permissions[i].getDescription());
            }
        }

        return message.toString();
    }
}
